module nade.shader;

import derelict.opengl.gl;
import derelict.opengl.glext;

import std.path;
import std.string;
import std.stream;


alias derelict.opengl.extension.arb.vertex_shader.GLhandleARB GLhandleARB;


class Shader {
	this(string path)
	{
		auto ext = tolower(getExt(path));
		if(ext == "vs")
		{
			_handle = glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB);
		}
		else if(ext == "fs")
		{
			_handle = glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB);
		}
		else
		{
			return;
		}

		string text;
		auto file = new File(path, FileMode.In);
		while(!file.eof())
		{
			char b; file.read(b);
			text ~= b;
		}
		
		char*[] textp = [ toStringz(text) ];
		int texts[] = [ text.length ];
		
		glShaderSourceARB(_handle, 1, textp.ptr, texts.ptr);

		glCompileShaderARB(_handle);
	}

	private {
		GLhandleARB _handle = 0;
	}
}


class ShaderProgram {
	this()
	{
		_handle = glCreateProgramObjectARB();
	}

	void opCatAssign(Shader shader)
	{
		glAttachObjectARB(_handle, shader._handle);
	}
	
	void link()
	{
		glLinkProgramARB(_handle);
	}
	
	void select()
	{
		glUseProgramObjectARB(_handle);
	}
	
	int uniformLocation(string name)
	{
		return glGetUniformLocationARB(_handle, toStringz(name));
	}

	private {
		GLhandleARB _handle = 0;
	}
}
